开发思路:三种 i18n 国际化资源加载的方式
概述
组件库的国际化(i18n)资源加载是组件库开发中的关键设计决策。本节介绍三种 i18n 资源加载方式,分析各自的优缺点和适用场景,并讲解如何在 playground 中测试组件库的打包产物。
组件库测试环境(Playground)
为什么需要 Playground
组件库打包后需要在独立环境中测试,不能直接在开发项目中测试:
| 原因 | 说明 |
|---|---|
| 环境隔离 | 避免开发项目的配置影响测试结果 |
| 模拟真实使用 | 从零配置,模拟用户实际使用场景 |
| 发现打包问题 | 暴露打包配置遗漏(如类型导出、样式引用) |
Playground 测试流程
创建独立 playground 项目
→ npm link 链接组件库
→ 从组件库导入组件
→ 运行测试
→ 发现问题(如 $t is not a function)
→ 修复组件库
→ 重新测试
text
常见打包坑点
| 问题 | 原因 | 解决方案 |
|---|---|---|
$t is not a function | 组件库使用了 i18n 但未正确导出 | 确保 vue-i18n 正确配置或提供 fallback |
| 类型未导出 | 打包配置未包含类型声明 | 配置 types 字段和 .d.ts 导出 |
| 样式缺失 | CSS 未正确打包或引用 | 检查打包配置的 style 入口 |
三种 i18n 资源加载方式
方式一:ESM 打包 + 外置依赖
// 方案一:将 i18n 模块以 ESM 格式打包,外置 vue-i18n 依赖
// vite.config.ts (组件库打包)
export default defineConfig({
build: {
lib: {
entry: 'src/index.ts',
formats: ['es'],
fileName: 'index'
},
rollupOptions: {
external: ['vue', 'vue-i18n'], // 外置 vue-i18n
output: {
globals: {
vue: 'Vue',
'vue-i18n': 'VueI18n'
}
}
}
}
})
typescript
优点:打包体积小,由宿主项目统一管理 vue-i18n 版本 缺点:宿主项目必须安装 vue-i18n
方式二:异步加载资源文件
// 方案二:使用 fetch 异步加载 i18n 资源文件
import { createI18n } from 'vue-i18n'
async function loadLocaleMessages(locale: string) {
const messages = await fetch(`/locales/${locale}.json`).then(r => r.json())
return messages
}
// 使用
const i18n = createI18n({
legacy: false,
locale: 'zh-CN',
fallbackLocale: 'en',
messages: {} // 初始为空,异步加载
})
// 按需加载
async function setLocale(locale: string) {
const messages = await loadLocaleMessages(locale)
i18n.global.setLocaleMessage(locale, messages)
i18n.global.locale.value = locale
}
typescript
优点:按需加载,不增加初始包体积 缺点:需要网络请求,首次加载有延迟
方式三:动态 import 加载
// 方案三:使用动态 import 加载资源模块
const messages = {
'zh-CN': () => import('./locales/zh-CN'),
'en': () => import('./locales/en'),
'zh-TW': () => import('./locales/zh-TW')
}
async function loadLocale(locale: string) {
const module = await messages[locale]()
return module.default
}
typescript
优点:构建工具自动代码分割,无需额外网络请求 缺点:需要构建工具支持
三种方式对比
| 维度 | 方式一:ESM 外置 | 方式二:fetch 异步 | 方式三:动态 import |
|---|---|---|---|
| 初始体积 | 小(外置) | 小(按需加载) | 中(代码分割) |
| 加载时机 | 页面加载时 | 按需加载 | 按需加载 |
| 网络请求 | 无额外请求 | 需要请求 JSON | 构建工具处理 |
| 离线支持 | 支持 | 不支持 | 支持 |
| 构建工具要求 | 低 | 无 | 需支持 code splitting |
| 适用场景 | 组件库通用方案 | 运行时加载 | SPA 应用 |
i18n 配置示例
// 组件库中的 i18n 配置
import { createI18n } from 'vue-i18n'
import zhCN from './locales/zh-CN'
import en from './locales/en'
export function setupI18n() {
return createI18n({
legacy: false,
locale: 'zh-CN',
fallbackLocale: 'en',
messages: {
'zh-CN': zhCN,
'en': en
}
})
}
typescript
实践要点
- 组件库打包后需在独立 playground 中测试,不能直接在开发项目中验证
- 三种 i18n 加载方式各有适用场景:ESM 外置适合组件库、fetch 适合运行时、动态 import 适合 SPA
- 组件库中如果使用了
$t函数,必须确保 vue-i18n 正确安装或提供 fallback - 打包配置需正确处理
external和globals,避免组件库重复打包 vue-i18n - 类型导出是组件库打包的常见遗漏点,需确保
.d.ts文件正确生成
↑